home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * *
- * Chatserver.m *
- * Copyright 1992 by Nik A Gervae *
- * *
- * Part of an example using the Objective-C classes (SktSocketManager, *
- * SktSocket, and SktSocketUser) which implement a convenient interface to *
- * Berkeley stream sockets under NeXTSTEP(r). See the accompanying class *
- * specifications (files with a .rtf or .spec suffix) and the sources for *
- * further information. *
- * *
- * NeXTSTEP is a registered trademark of NeXT Computer, Inc. *
- * *
- ****************************************************************************
- * *
- * LICENSE *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation. *
- * *
- * The program and this makefile are distributed in the hope that it will *
- * be useful, but are provided "AS IS" AND WITHOUT ANY WARRANTY; without *
- * any express or implied warranty of MERCHANTABILITY or FITNESS FOR A *
- * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
- * Any use or distribution of the program and documentation must include *
- * appropriate copyrights to acknowledge Nik A. Gervae and the Free *
- * Software Foundation, Inc. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- * *
- ****************************************************************************
- * *
- * VERSION HISTORY *
- * *
- * Version numbers are simply dates in the form YYYYMMDD. These represent *
- * the date that version was finished. Only significantly changed versions *
- * are reported here, or those versions requiring explanation of changes. *
- * There may be many interim stages between dated versions. *
- * *
- * DateVersion Primary Author Notes *
- * ----------- --------------- -------------------------------------------- *
- * 19920327 Nik A Gervae First released version *
- * *
- ***************************************************************************/
-
- #import <stdio.h>
- #import <string.h>
-
- #import <objc/Object.h>
- #import <objc/List.h>
-
- #import "SktSocketManager.h"
- #import "SktSocket.h"
- #import "Chatserver.h"
- #import "Guest.h"
-
- /***************************************************************************
- * *
- * These are the constant strings used. Feel free to translate them into *
- * your favorite language. Do be sure to keep all the % directives in *
- * place, or change the code that accesses these strings. *
- * *
- ***************************************************************************/
- #define STR_RunningOnAddresses "Running on %s at Internet addresses:"
- #define STR_AnAddress " %s"
- #define STR_InetServicePort "Internet service port number: %d\n"
- #define STR_EndOfAddresses "\n"
-
-
-
- @implementation Chatserver
-
- /***************************************************************************
- * *
- * initWithInetPort: *
- * *
- * Creates a SocketMgr object and initializes the guestList. Also logs *
- * the host, address and port number the server is running on. *
- * *
- ***************************************************************************/
- - initWithInetPort:(int)inetPort
- {
- char **addresses;
- int i;
-
- /*
- * Get a manager, bomb if you can't.
- */
- socketMgr = [[SktSocketManager alloc] initPort:inetPort logfile:stderr
- fdCapacity:10 userClass:[Guest class]];
- if (!socketMgr) return [self free];
-
- /*
- * Try to print out all the internet addresses for this machine.
- */
- if (NULL != (addresses = [socketMgr getInetAddresses])) {
- [self log:STR_RunningOnAddresses, [socketMgr hostname]];
- for (i = 0; NULL != addresses[i]; i++) {
- [self log:STR_AnAddress, addresses[i]];
- }
- [self log:STR_EndOfAddresses];
- free(addresses);
- }
-
- /*
- * Print out the port number.
- */
- [self log:STR_InetServicePort, [socketMgr servicePort]];
-
- /*
- * A new guest list, please.
- */
- guestList = [[List alloc] init];
-
- return self;
- }
-
- /***************************************************************************
- * *
- * run *
- * *
- * Run forever. The -stop message never gets sent. Excercise for the *
- * reader. *
- * *
- ***************************************************************************/
- - run
- {
- running = YES;
- while(running) {
- usleep(250000);
- [self update];
- }
- return self;
- }
-
- /***************************************************************************
- * *
- * update *
- * *
- * socketMgr needs this to work. Tell socketMgr to update, and do the same *
- * for each guest. *
- * *
- ***************************************************************************/
- - update
- {
- [socketMgr update];
- [guestList makeObjectsPerform:@selector(update)];
- return self;
- }
-
- /***************************************************************************
- * *
- * guestDidInit: *
- * *
- * Any newly created Guest sends this. This just saves it in the guest list *
- * for further reference. *
- * *
- ***************************************************************************/
- - guestDidInit:aGuest
- {
- [guestList addObject:aGuest];
- return self;
- }
-
- /***************************************************************************
- * *
- * guestWillFree: *
- * *
- * A guest send this as its about to die. This just removes it from the *
- * guest list *
- ***************************************************************************/
- - guestWillFree:aGuest
- {
- [guestList removeObject:aGuest];
- return self;
- }
-
- /***************************************************************************
- * *
- * log: *
- * *
- * Write out a printf() style argument list to stderr. *
- * *
- ***************************************************************************/
- - log:(const char *)format, ...
- {
- va_list param_list;
-
- va_start(param_list, format);
- vfprintf(stderr, format, param_list);
- fflush(stderr);
- va_end(param_list);
- return self;
- }
-
- /***************************************************************************
- * *
- * announce: *
- * *
- * Tell something to every guest. *
- * *
- ***************************************************************************/
- - announce:(const char *)announcement
- {
- int numGuests;
- int i;
-
- numGuests = [guestList count];
- for (i = 0; i < numGuests; i++) {
- [[guestList objectAt:i] queueOutputString:announcement];
- }
-
- return self;
- }
-
- /***************************************************************************
- * *
- * announce:except: *
- * *
- * Tell something to every guest except the one mentioned. *
- * *
- ***************************************************************************/
- - announce:(const char *)announcement except:notMe
- {
- int numGuests;
- int i;
- id currentGuest;
-
- numGuests = [guestList count];
- for (i = 0; i < numGuests; i++) {
- currentGuest = [guestList objectAt:i];
- if (currentGuest != notMe) [currentGuest queueOutputString:announcement];
- }
-
- return self;
- }
-
- /***************************************************************************
- * *
- * stop *
- * *
- * Should be reasonably clear. Except that it never gets sent! :-) *
- * *
- ***************************************************************************/
- - stop
- {
- running = NO;
- return self;
- }
-
- /***************************************************************************
- * *
- * shutdown *
- * *
- * If there were more complex structures/objects, you might want to save *
- * them to disk or free them all here. *
- * *
- ***************************************************************************/
- - shutdown
- {
- return [self free];
- }
-
-
- @end /*implementation Chatserver*/
-
- /***************************************************************************
- ***************************************************************************/
-